home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
elk-2_0.lha
/
elk-2.0
/
src
/
symbol.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-11
|
5KB
|
247 lines
#include <ctype.h>
#include "scheme.h"
Object Obarray;
Object Null,
True,
False,
Unbound,
Special,
Void,
Newline,
Eof,
Zero,
One;
Init_Symbol () {
SETTYPE(Null, T_Null);
SETTYPE(True, T_Boolean); SETFIXNUM(True, 1);
SETTYPE(False, T_Boolean); SETFIXNUM(False, 0);
SETTYPE(Unbound, T_Unbound);
SETTYPE(Special, T_Special);
SETTYPE(Void, T_Void);
SETTYPE(Eof, T_End_Of_File);
Newline = Make_Char ('\n');
Zero = Make_Fixnum (0);
One = Make_Fixnum (1);
Obarray = Make_Vector (OBARRAY_SIZE, Null);
Global_GC_Link (Obarray);
}
Object Make_Symbol (name) Object name; {
Object sym;
register struct S_Symbol *sp;
GC_Node;
GC_Link (name);
sym = Alloc_Object (sizeof (struct S_Symbol), T_Symbol, 0);
sp = SYMBOL(sym);
sp->name = name;
sp->value = Unbound;
sp->plist = Null;
GC_Unlink;
return sym;
}
Object P_Symbolp (x) Object x; {
return TYPE(x) == T_Symbol ? True : False;
}
Object P_Symbol_To_String (x) Object x; {
Check_Type (x, T_Symbol);
return SYMBOL(x)->name;
}
Object Obarray_Lookup (str, len) register char *str; register len; {
register h;
register struct S_String *s;
register struct S_Symbol *sym;
Object p;
h = Hash (str, len) % OBARRAY_SIZE;
for (p = VECTOR(Obarray)->data[h]; !Nullp (p); p = sym->next) {
sym = SYMBOL(p);
s = STRING(sym->name);
if (s->size == len && bcmp (s->data, str, len) == 0)
return p;
}
return Make_Fixnum (h);
}
Object CI_Intern (str) char *str; {
Object s, *p, sym, ostr;
register len;
register char *src;
char *dst;
char buf[128];
Alloca_Begin;
len = strlen (str);
if (len > sizeof(buf)) {
Alloca (dst, char*, len);
} else
dst = buf;
src = str;
str = dst;
for ( ; *src; src++, dst++)
*dst = isupper (*src) ? tolower (*src) : *src;
s = Obarray_Lookup (str, len);
if (TYPE(s) != T_Fixnum) {
Alloca_End;
return s;
}
ostr = Make_Const_String (str, len);
sym = Make_Symbol (ostr);
p = &VECTOR(Obarray)->data[FIXNUM(s)];
SYMBOL(sym)->next = *p;
Alloca_End;
return *p = sym;
}
Object Intern (str) char *str; {
Object s, *p, sym, ostr;
register len;
if (Case_Insensitive)
return CI_Intern (str);
len = strlen (str);
s = Obarray_Lookup (str, len);
if (TYPE(s) != T_Fixnum)
return s;
ostr = Make_Const_String (str, len);
sym = Make_Symbol (ostr);
p = &VECTOR(Obarray)->data[FIXNUM(s)];
SYMBOL(sym)->next = *p;
return *p = sym;
}
Object P_String_To_Symbol (str) Object str; {
Object s, *p, sym;
Check_Type (str, T_String);
s = Obarray_Lookup (STRING(str)->data, STRING(str)->size);
if (TYPE(s) != T_Fixnum)
return s;
str = Make_String (STRING(str)->data, STRING(str)->size);
sym = Make_Symbol (str);
p = &VECTOR(Obarray)->data[FIXNUM(s)];
SYMBOL(sym)->next = *p;
return *p = sym;
}
Object P_Oblist () {
register i;
Object p, list, bucket;
GC_Node2;
p = list = Null;
GC_Link2 (p, list);
for (i = 0; i < OBARRAY_SIZE; i++) {
bucket = Null;
for (p = VECTOR(Obarray)->data[i]; !Nullp (p); p = SYMBOL(p)->next)
bucket = Cons (p, bucket);
if (!Nullp (bucket))
list = Cons (bucket, list);
}
GC_Unlink;
return list;
}
Object P_Put (argc, argv) Object *argv; {
Object sym, key, last, tail, prop;
GC_Node3;
sym = argv[0];
key = argv[1];
Check_Type (sym, T_Symbol);
Check_Type (key, T_Symbol);
last = Null;
for (tail = SYMBOL(sym)->plist; !Nullp (tail); tail = Cdr (tail)) {
prop = Car (tail);
if (EQ(Car (prop), key)) {
if (argc == 3)
Cdr (prop) = argv[2];
else if (Nullp (last))
SYMBOL(sym)->plist = Cdr (tail);
else
Cdr (last) = Cdr (tail);
return key;
}
last = tail;
}
if (argc == 2)
return False;
GC_Link3 (sym, last, key);
tail = Cons (key, argv[2]);
tail = Cons (tail, Null);
if (Nullp (last))
SYMBOL(sym)->plist = tail;
else
Cdr (last) = tail;
GC_Unlink;
return key;
}
Object P_Get (sym, key) Object sym, key; {
Object prop;
Check_Type (sym, T_Symbol);
Check_Type (key, T_Symbol);
prop = Assq (key, SYMBOL(sym)->plist);
if (!Truep (prop))
return False;
/*
* Do we want to signal an error or return #f?
*
* Primitive_Error ("~s has no such property: ~s", sym, key);
*/
return Cdr (prop);
}
Object P_Symbol_Plist (sym) Object sym; {
Check_Type (sym, T_Symbol);
return Copy_List (SYMBOL(sym)->plist);
}
Hash (str, len) char *str; {
register h;
register char *p, *ep;
h = 5 * len;
if (len > 5)
len = 5;
for (p = str, ep = p+len; p < ep; ++p)
h = (h << 2) ^ *p;
return h & 017777777777;
}
Define_Symbol (sym, name) Object *sym; char *name; {
*sym = Intern (name);
Func_Global_GC_Link (sym);
}
void Define_Variable (var, name, init) Object *var, init; char *name; {
Object frame, sym;
GC_Node;
GC_Link (init);
sym = Intern (name);
SYMBOL(sym)->value = init;
frame = Add_Binding (Car (The_Environment), sym, init);
*var = Car (frame);
Car (The_Environment) = frame;
Func_Global_GC_Link (var);
GC_Unlink;
}
Object Var_Get (var) Object var; {
return Cdr (var);
}
void Var_Set (var, val) Object var, val; {
Cdr (var) = val;
SYMBOL (Car (var))->value = val;
}